﻿// HSS.ServiceModel.Internal.MessageInspectorChannelFactory.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       MessageInspectorChannelFactory.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
namespace HSS.ServiceModel.Internal
{
	#region Using Directives
	using System;
	using System.ServiceModel;
	using System.ServiceModel.Channels;
	#endregion

	#region MessageInspectorChannelFactory
	/// <summary>
	/// The Factory responsible for creating MessageInspector Channels. This code is not meant to be called from user code.
	/// </summary>
	[System.Diagnostics.DebuggerStepThroughAttribute()]
	internal sealed class MessageInspectorChannelFactory : ChannelFactoryBase<IRequestChannel>
	{
		#region Fields
		private IChannelFactory<IRequestChannel> innerChannelFactory;
		private IMessageInspector messageInspector;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="innerChannelFactory">The factory being wrapped by this factory.</param>
		/// <param name="messageInspector">The message inspector used to inspect out-bound (request) messages.</param>
		public MessageInspectorChannelFactory(IChannelFactory<IRequestChannel> innerChannelFactory, IMessageInspector messageInspector)
		{
			this.messageInspector = messageInspector;
			this.innerChannelFactory = innerChannelFactory;
		}
		#endregion

		#region Overrides

		/// <summary>
		/// Returns a typed object requested, if present, from the appropriate layer in the channel stack.
		/// </summary>
		/// <typeparam name="T">The typed object for which the method is querying.</typeparam>
		/// <returns>The typed object T requested, if it is present or null if it is not.</returns>
		public override T GetProperty<T>()
		{
			return innerChannelFactory.GetProperty<T>();
		}
		/// <summary>
		/// The extension point, in which the MessageInspector wraps the communication channel.
		/// </summary>
		/// <param name="to">The System.ServiceModel.EndpointAddress of the remote endpoint to which the channel sends messages.</param>
		/// <param name="via">The System.Uri that contains the transport address to which messages are sent on the output channel.</param>
		/// <returns>A channel of type IRequestChannel, with the specified addresses.</returns>
		protected override IRequestChannel OnCreateChannel(EndpointAddress to, Uri via)
		{
			IRequestChannel innerchannel = innerChannelFactory.CreateChannel(to, via);
			MessageInspectorChannel clientChannel = new MessageInspectorChannel(this, innerchannel, messageInspector);

			return (IRequestChannel)clientChannel;
		}

		#region Wrapped base calls
		protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
		{
			return innerChannelFactory.BeginOpen(timeout, callback, state);
		}
		protected override void OnEndOpen(IAsyncResult result)
		{
			innerChannelFactory.EndOpen(result);
		}

		protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
		{
			return innerChannelFactory.BeginClose(timeout, callback, state);
		}
		protected override void OnEndClose(IAsyncResult result)
		{
			innerChannelFactory.EndClose(result);
		}

		protected override void OnAbort()
		{
			innerChannelFactory.Abort();
		}
		protected override void OnOpen(TimeSpan timeout)
		{
			innerChannelFactory.Open(timeout);
		}
		protected override void OnClose(TimeSpan timeout)
		{
			innerChannelFactory.Close(timeout);
		}
		#endregion

		#endregion
	}
	#endregion
}